package com.yl.chainStore.control.warehouse


import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.yl.chainStore.common.Constants
import com.yl.chainStore.common.enums.Status
import com.yl.chainStore.common.enums.TypeEnum
import com.yl.chainStore.control.BaseCtrl
import com.yl.chainStore.entity.warehouse.WarehouseGoodSupplier
import com.yl.chainStore.entity.warehouse.WarehouseInOrder
import com.yl.chainStore.pojo.vo.WebSelectVo
import com.yl.chainStore.pojo.vo.warehouse.WarehouseGoodSupplierSelectVo
import com.yl.chainStore.pojo.vo.warehouse.WarehouseInOrderSelectVo
import com.yl.chainStore.services.warehouse.IWarehouseInOrderService
import com.yl.chainStore.services.warehouse.IWarehouseService
import com.yl.chainStore.services.IWebCompanyUserService
import com.yl.common.ErrorCode
import com.yl.common.control.ResponseBody
import com.yl.common.control.returnError
import com.yl.common.control.returnSuccess
import com.yl.common.getContext
import com.yl.users.common.annotations.PermsCode
import com.yl.users.entity.CompanyDept
import com.yl.users.entity.CompanyUser
import com.yl.users.pojo.vo.CompanyDeptSelectVo
import com.yl.users.pojo.vo.CompanyUserSelectVo
import com.yl.users.services.ICompanyDeptService
import com.yl.users.services.ISysCompanyService
import org.springframework.transaction.annotation.Transactional
import org.springframework.transaction.interceptor.TransactionAspectSupport
import org.springframework.web.bind.annotation.*
import java.math.BigDecimal
import java.math.RoundingMode

/**
 * 入库订单管理
 */
@RestController
@RequestMapping("warehouse/inOrder")
open class WarehouseInOrderController(
	private val inOrderService: IWarehouseInOrderService,
	private val iWarehouseService: IWarehouseService,
	private val iSysCompanyService: ISysCompanyService,
	private val iCompanyDeptService: ICompanyDeptService,
	private val iWebCompanyUserService: IWebCompanyUserService,
) : BaseCtrl() {

	/**
	 * 入库订单列表
	 */
	@PostMapping("inOrderPage")
	@PermsCode("warehouse:inOrder:list")
	@Transactional
	open fun inOrderPage(@RequestBody vo: WarehouseInOrderSelectVo): ResponseBody {
		val page = Page<WarehouseInOrder>(vo.current, vo.size)
		return returnSuccess(
			iWarehouseService.inOrderPage(page, vo)
		)
	}

	/**
	 * 入库明细
	 */
	@GetMapping("inOrderDetail/{id}")
	@PermsCode("warehouse:inOrder:inOrderDetail")
	@Transactional
	open fun inOrderDetail(@PathVariable id: Long): ResponseBody {
		val inOrder = inOrderService.getInOrder(id)
		if(inOrder != null){
			inOrder.details = inOrderService.inOrderDetails(id)
		}
		return returnSuccess(inOrder)
	}

	/**
	 * 暂存
	 */
	@PostMapping("staging")
	@Transactional(rollbackFor = [Exception::class])
	open fun staging(@RequestBody inOrder: WarehouseInOrder):ResponseBody{
		checkInLog(inOrder)
		if(inOrder.id != 0L){
			//如果有草稿，删除之前的草稿，新增一个草稿
			inOrderService.deleteInOrder(inOrder.id)
		}
		inOrder.id = 0L
		val addInOrder = iWebCompanyUserService.stagingInOrder(inOrder)
		if (addInOrder.code != ErrorCode.SUCCESS.code) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
			return addInOrder
		}
		if(inOrder.details != null){
			for (detail in inOrder.details!!) {
				detail.inOrderId = inOrder.id
				detail.status = Status.STAGING
				inOrderService.addDetail(detail)
			}
		}

		return returnSuccess()
	}

	@GetMapping("getStaging")
	@Transactional
	open fun getStaging():ResponseBody{
		val stagingInOrder = iWebCompanyUserService.getStagingInOrder(getContext().userId, getContext().subCompanyId)
		if(stagingInOrder != null){
			stagingInOrder.details = inOrderService.inOrderDetails(stagingInOrder.id)
		}
		return returnSuccess(stagingInOrder)
	}

	/**
	 * 入库单申请
	 */
	@PostMapping("addInOrder")
	@Transactional(rollbackFor = [Exception::class])
	@PermsCode("warehouse:inOrder:add")
	open fun addInOrder(@RequestBody inOrder: WarehouseInOrder): ResponseBody {
		if(inOrder.id != 0L){
			//如果有草稿，删除之前的草稿，
			inOrderService.deleteInOrder(inOrder.id)
		}
		inOrder.id = 0L
		val checkInLog = checkInLog(inOrder)
		if(checkInLog.code != ErrorCode.SUCCESS.code){
			return checkInLog
		}
		val addInOrder = iWarehouseService.addInOrder(inOrder)
		if (addInOrder.bodyIsError()) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
			return addInOrder
		}
		var i = 1
		for (detail in inOrder.details!!) {
			if (detail.goodCount == 0) {
				return returnError(ErrorCode.DATA_SAVE_FAILED, "第" + i + "行物品错误：请输入物品数量")
			}
			detail.inOrderId = inOrder.id
			detail.status = Status.WAIT_AUDIT
			val addDetail = inOrderService.addDetail(detail)
			if (addDetail.code != ErrorCode.SUCCESS.code) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
				return returnError(ErrorCode.DATA_SAVE_FAILED, "第" + i + "行物品错误：" + addDetail.msg)
			}
			i++
		}
		return returnSuccess()
	}

	private fun checkInLog(inOrder: WarehouseInOrder):ResponseBody{
		when (inOrder.type) {
			TypeEnum.WAREHOUSE_IN_TYPE_SUPPLIER -> {
				if (inOrder.inTypeObjectId == null) {
					return returnError(ErrorCode.PARAM_EMPTY, "请选择供应商")
				}
				inOrder.supplierId = inOrder.inTypeObjectId
			}
			TypeEnum.WAREHOUSE_IN_TYPE_USER -> {
				if (inOrder.inTypeObjectId == null) {
					return returnError(ErrorCode.PARAM_EMPTY, "请选择退领用户")
				}
				inOrder.inWarehouseUserId = inOrder.inTypeObjectId
			}
			TypeEnum.WAREHOUSE_IN_TYPE_DEPT -> {
				if (inOrder.inTypeObjectId == null) {
					return returnError(ErrorCode.PARAM_EMPTY, "请选择退领部门")
				}
				inOrder.inWarehouseDeptId = inOrder.inTypeObjectId
			}
			TypeEnum.OTHER -> {

			}

			else -> {
			}
		}
		return returnSuccess()
	}

	/**
	 * 入库审核通过
	 */
	@PostMapping("performInWarehouseOrder/{id}")
	@Transactional(rollbackFor = [Exception::class])
	@PermsCode("warehouse:inOrder:audit")
	open fun performInWarehouseOrder(@PathVariable id: Long): ResponseBody {
		val completeInOrder = inOrderService.completeInOrder(id)
		if (completeInOrder.code != ErrorCode.SUCCESS.code) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
		}
		return completeInOrder
	}


	/**
	 * 入库审核失败
	 */
	@PostMapping("noPassInWarehouseLog/{id}")
	@Transactional(rollbackFor = [Exception::class])
	@PermsCode("warehouse:inOrder:audit")
	open fun noPassInWarehouseLog(@PathVariable id: Long): ResponseBody {
		val completeInOrder = inOrderService.noPassInOrder(id)
		if (completeInOrder.code != ErrorCode.SUCCESS.code) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
		}
		return completeInOrder
	}

	/**
	 * 取消入库（作废）
	 */
	@PostMapping("cancelInWarehouseOrder/{id}")
	@Transactional(rollbackFor = [Exception::class])
	@PermsCode("warehouse:inOrder:cancel")
	open fun cancelInWarehouseOrder(@PathVariable id: Long): ResponseBody {
		val completeInOrder = inOrderService.cancelInOrder(id)
		if (completeInOrder.code != ErrorCode.SUCCESS.code) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
		}
		return completeInOrder
	}

	/**
	 * 获取用户类型
	 */
	@GetMapping("getInOrderType")
	open fun getInOrderType(): ResponseBody {
		val list = mutableListOf<Map<String, Any>>()
		list.add(TypeEnum.WAREHOUSE_IN_TYPE_SUPPLIER.getMap())
		list.add(TypeEnum.WAREHOUSE_IN_TYPE_USER.getMap())
		list.add(TypeEnum.WAREHOUSE_IN_TYPE_DEPT.getMap())
		list.add(TypeEnum.OTHER.getMap())
		return returnSuccess(list)
	}


	@PostMapping("getInOrderTypeObjectListByType")
	@Transactional
	open fun getInOrderTypeObjectListByType(@RequestBody body: JSONObject): ResponseBody {
		val name = body.getString("name")
		val type = body.getString("type")
		val list = mutableListOf<Map<String, Any>>()
		when (type) {
			TypeEnum.WAREHOUSE_IN_TYPE_SUPPLIER.typeName -> {
				val vo = WarehouseGoodSupplierSelectVo()
				vo.name = name
				vo.deptId = getContext().subCompanyId
				val page =
					iWarehouseService.supplierPage(Page<WarehouseGoodSupplier>(1, 10), vo)
				for (item in page.records) {
					val mutableMapOf = mutableMapOf<String, Any>()
					mutableMapOf["id"] = item.id
					mutableMapOf["name"] = item.name
					list.add(mutableMapOf)
				}
			}
			TypeEnum.WAREHOUSE_IN_TYPE_USER.typeName -> {
				val companyUserSelectVo = CompanyUserSelectVo(realName = name)
				val page =
					iCompanyDeptService.getSubCompanyUserPage(Page<CompanyUser>(1, 10), companyUserSelectVo, getContext().subCompanyId)
				for (item in page.records) {
					val mutableMapOf = mutableMapOf<String, Any>()
					mutableMapOf["id"] = item.id
					mutableMapOf["name"] = item.realName
					list.add(mutableMapOf)
				}
			}
			TypeEnum.WAREHOUSE_IN_TYPE_DEPT.typeName -> {
				val companyDeptSelectVo = CompanyDeptSelectVo(name = name)

				val page =
					iCompanyDeptService.getSubCompanyDeptPage(Page<CompanyDept>(1, 10), companyDeptSelectVo)
				for (item in page.records) {
					val mutableMapOf = mutableMapOf<String, Any>()
					mutableMapOf["id"] = item.id
					mutableMapOf["name"] = item.name
					list.add(mutableMapOf)
				}
			}
			TypeEnum.OTHER.typeName -> {

			}

		}
		return returnSuccess(list)
	}

	@GetMapping("getUserList")
	@Transactional
	open fun getUserList(value: String?): ResponseBody {

		val userPage = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 10),
			CompanyUserSelectVo(realName = value),
			getContext().subCompanyId,
		)
		val list = mutableListOf<WebSelectVo>()
		for(user in userPage.records){
			list.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(list)
	}
}
